
//
// 101021 - AH - Created.
// 101116 - AH - getForest().
// 101214 - AH - Finished implementation now that retrieval strategies 
//               algorithms been done.
// 101228 - AH - Minor java doc fix, bug discovered by java doc compiler.
// 110108 - AH - Override new Spoke method rinse().
// 110109 - AH - (Hector) Introducing the RetrievalEvent.
// 110110 - AH - Implemented new Spoke method getInput(List<AttributeObject>).
// 110117 - AH - (Hector) Renamed getInput(List<AttributeObject>) to
//               getToken(List<AttributeObject>) to be true to terminology.
// 110709 - AH - (Garage) getOnotology().
// 120117 - AH - (Huset) Renamed from *Spoke.
// 120228 - AH - (Zen *) Implemented new Ontology method 
//               getSoekratNames(List<SoekratNames>).
//

package org.soekrat.engine.wheel.ontology;

import java.util.ArrayList;
import java.util.List;

import org.soekrat.AttributeObject;
import org.soekrat.engine.SoekratName;
import org.soekrat.engine.forest.Forest;
import org.soekrat.engine.forest.Tree;
import org.soekrat.engine.ontology.OntologyDatastructure;
import org.soekrat.engine.retrieval.forest.ForestRetrievalStrategy;
import org.soekrat.engine.retrieval.forest.ForestScan;
import org.soekrat.engine.visitor.Input;
import org.soekrat.engine.wheel.Wheel;
import org.soekrat.engine.wheel.retrieval.RetrievalEvent;
import org.soekrat.engine.wheel.retrieval.RetrievalEventSource;
import org.soekrat.engine.wheel.retrieval.RetrievalEventType;

/**
 * <p>
 *   {@link Forest}
 *   {@link Ontology spoke}.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC) 
 */
public final class ForestOntology extends Ontology 
{
  private final RetrievalEventSource m_source=RetrievalEventSource.FOREST;
  
  private final RetrievalEventType m_step=RetrievalEventType.STEP;
  
  private final Forest m_forest;
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param wheel  {@link Wheel} {@code this} 
   *               {@link Ontology} belong to.
   * @param forest {@link Forest} {@code this} searches.
   */
  public ForestOntology(Wheel wheel, Forest forest)
  {
    super(wheel);
    
    if (forest==null)
    {
      throw new NullPointerException("forest");
    }
    
    m_forest=forest;
  }
  
  @Override
  public List<SoekratName> getSoekratNames(List<SoekratName> names) 
  {
    names=(names==null) ? new ArrayList<SoekratName>() : names;
    
    for (Tree root : m_forest) getSoekratNames(root, names);
    
    return names;
  }
  
  private void getSoekratNames(Tree root, List<SoekratName> names)
  {
    names.add(root.getSoekratName());
    int n=root.getChildCount();
    for (int i=0; i<n; i++)
    {
      Tree child=root.getChild(i);
      getSoekratNames(child, names);
    }
  }
  

  /**
   * <p>
   *   Gets
   *   {@link Forest} {@code this} access.
   * </p>
   * @return {@code Forest}.
   */
  public Forest getForest(){ return m_forest; }

  @Override
  public OntologyDatastructure getOntologyDatastructure(){ return m_forest; }
  
  @Override
  protected Object scan(Input keywords)
  {
    return new ForestScan(m_forest, keywords);
  }

  @Override
  protected RetrievalEvent paint(Object scan, List<AttributeObject> paint) 
  {
    RetrievalEvent retVal=new RetrievalEvent("Forest", m_step, m_source);
    ForestRetrievalStrategy.retrieve((ForestScan)scan, paint, retVal);
    return retVal;
  }

  @Override
  public void rinse(){ ForestRetrievalStrategy.rinse(m_forest); }

  @Override
  public Input getTokens(List<AttributeObject> paint) 
  {
    if (paint==null)
    {
      throw new NullPointerException("paint");
    }
    
    Input retVal=new Input();
    
    for (AttributeObject curr : paint) 
    {
      if (curr instanceof Tree) retVal.add(curr.getName());  
    }

    return retVal;
  }
  
  @Override
  public String getName(){ return "Forest Ontology"; }
  
}
